package com.situ.util;

import com.situ.annotation.Param;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Enumeration;

public class BaseServlet extends HttpServlet {

    private static final long serialVersionUID = -3643747821372738799L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("utf-8");
        String action = req.getParameter("action");
        if (action == null) {
            action = "list";
        }
        Method[] methods = this.getClass().getDeclaredMethods();
        Method method = null;
        for (Method m : methods) {
            if (m.getName().equals(action)) {
                method = m;
                break;
            }
        }
        method.setAccessible(true);
        invokeMethod(method, req, resp);
    }

    private void invokeMethod(Method method, HttpServletRequest req, HttpServletResponse resp) {
        Parameter[] ps = method.getParameters();//获取这个方法里所有的参数
        Class<?>[] cs = method.getParameterTypes();//获取所有参数对应的类型
        Object[] args = new Object[ps.length];

        for (int i = 0; i < ps.length; i++) {

            String paramName = "";
            Param ann = ps[i].getAnnotation(Param.class);
            if(ann!=null){
                paramName = ann.value();
            }
            if (cs[i].equals(int.class)) {
                args[i] = 0;
            } else if (cs[i].equals(double.class)) {
                args[i] = 0;
            }


            if (cs[i].equals(HttpServletRequest.class)) {
                args[i] = req;
            } else if (cs[i].equals(HttpServletResponse.class)) {
                args[i] = resp;
            } else if (cs[i].equals(HttpSession.class)) {
                args[i] = req.getSession();
            } else if (cs[i].equals(Integer.class) || cs[i].equals(int.class)) {
                String arg = req.getParameter(paramName);
                if (arg != null) {
                    args[i] = Integer.parseInt(arg);
                }
            } else if (cs[i].equals(double.class) || cs[i].equals(Double.class)) {
                String arg = req.getParameter(paramName);
                if (arg != null) {
                    args[i] = Double.parseDouble(arg);
                }
            } else if (cs[i].equals(String.class)) {
                args[i] = req.getParameter(paramName);
            } else {
                try {
                    Object obj = cs[i].newInstance();
                    Enumeration<String> names = req.getParameterNames();
                    while (names.hasMoreElements()) {
                        String name = names.nextElement();
                        try {
                            Field field = cs[i].getDeclaredField(name);
                            field.setAccessible(true);
                            String param = req.getParameter(name);
                            if (field.getType().equals(Integer.class)) {
                                field.set(obj, Integer.parseInt(param));
                            } else if (field.getType().equals(Double.class)) {
                                field.set(obj, Double.parseDouble(param));
                            } else {
                                field.set(obj, param);
                            }
                        } catch (Exception ignore) {

                        }
                    }
                    args[i] = obj;
                } catch (Exception ignore) {
                }
            }
        }
        try {
            method.invoke(this, args);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
